package ui;

import info.Conference;
import info.Manuscript;
import info.Recommendation;
import io.RecommendationAccess;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.text.JTextComponent;

import org.jdom2.JDOMException;

import users.SubprogramChair;

/**
 * This panel mimics the layout of the recommendation form.  It can double
 * as a form to fill out, and as a display for previously submitted forms.
 * 
 * @author Aaron Chen
 * @version 3/6/2014
 */
@SuppressWarnings("serial")
public class RecommendationPanel extends AbstractForm {
  
  /** The text field for the Subprogram Chair's name. */
  private JTextField my_tf_spc;
  
  /** The text field for the conference that the manuscript is associated
   * with. */
  private JTextField my_tf_conference_name;
  
  /** The text field for the manuscript's author. */
  private JTextField my_tf_manuscript_author;
  
  /** The text field for the manuscript's title. */
  private JTextField my_tf_manuscript_title;
  
  /** The radio button group for the recommendation summary. */
  private ButtonGroup my_group_summary;
  
  /** The text area for the Subprogram Chair's rationale for his summary rating. */
  private JTextArea my_ta_rationale;

  /** The database access that handles Recommendation objects. */
  private RecommendationAccess my_recommendation_access;
  
  /** The Recommendation object being represented by this form. */
  private Recommendation my_recommendation;

  
  /**
   * Initializes the panel with empty fields.
   * @param the_parent The main application window container.
   */
  public RecommendationPanel(final DisplayPanel the_parent) {
    super(the_parent);
    my_recommendation_access = getRecommendationAccess();
    my_btn_submit.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent the_e) {
        //MainPage.r = submitForm();
        submitForm();
        JOptionPane.showMessageDialog(RecommendationPanel.this,
                                      "Form submitted successfully!");
        setMode(MODE_EXISTING_FORM);
      }
    });
    my_btn_save_changes.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(final ActionEvent the_e) {
        //TODO add a check to see if the the recommendation deadline is past.
        //MainPage.r = submitForm();
        editForm();
        JOptionPane.showMessageDialog(RecommendationPanel.this,
                                      "Form edited successfully!");
      }
    });
  }
  
  /**
   * Initializes the panel with filled out fields.  Use this constructor if you
   * want to view a form that has been previously filled out.
   * @param the_parent The main application window container.
   * @param the_r The recommendation form that was filled out previously.
   */
  public RecommendationPanel(final DisplayPanel the_parent, final Recommendation the_r) {
    this(the_parent);
    setMode(MODE_EXISTING_FORM);
    populateFields(the_r);
  }
  
  /**
   * Initializes the panel with filled out fields.  Use this constructor if you
   * want to view a form that has been previously filled out.
   * @param the_parent The main application window container.
   * @param the_spc The Subprogram Chair that will fill out this form.
   * @param the_m The manuscript for which this form is being filled out for.
   */
  public RecommendationPanel(final DisplayPanel the_parent,
                             final SubprogramChair the_spc,
                             final Manuscript the_m) {
    this(the_parent);
    final long conf_id = the_spc.getConferenceID();
    final Conference c = MainPage.getDatabase().accessConf().getConference(conf_id);
    setConferenceFields(c);
    setManuscriptFields(the_m);
    setUserFields(the_spc);
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected String getFormTitle() {
    return "Recommendation Form";
  }
  
  /**
   * Attempts to create a RecommendationAccess connection to the database.
   * @return The RecommendationAccess object.
   */
  private RecommendationAccess getRecommendationAccess() {
    RecommendationAccess database = null;
    try {
      database = new RecommendationAccess();
    } catch (final IOException e) {
      JOptionPane.showMessageDialog(this, "There is a problem accessing the database.");
      e.printStackTrace();
    } catch (final JDOMException e) {
      JOptionPane.showMessageDialog(this, "The file specified by the code is incorrect.");
      e.printStackTrace();
    }
    return database;
  }

  /**
   * {@inheritDoc}
   */
  @Override
  protected JPanel createFormPanel() {
    final JPanel panel_form = new JPanel();
    panel_form.setLayout(new BoxLayout(panel_form, BoxLayout.Y_AXIS));
    panel_form.setBackground(Standards.COLOR_BACKGROUND);
    panel_form.setBorder(Standards.BORDER_COMPOUND_FORM);
    
    panel_form.add(createColumnedPanel());
    panel_form.add(Box.createVerticalStrut(Standards.STRUT_LENGTH_MEDIUM));

    my_group_summary = new ButtonGroup();
    panel_form.add(createRadioButtonQuestion("Summary", my_group_summary));
    
    panel_form.add(Box.createVerticalStrut(Standards.STRUT_LENGTH_MEDIUM));
    
    final JPanel panel_rationale = new JPanel();
    panel_rationale.setBackground(Standards.COLOR_BACKGROUND);
    panel_form.add(panel_rationale);
    panel_rationale.setLayout(new BorderLayout(0, 0));
    
    final JLabel lbl_rationale = new JLabel("Rationale");
    panel_rationale.add(lbl_rationale, BorderLayout.CENTER);
    
    my_ta_rationale = new JTextArea();
    my_ta_rationale.setToolTipText("This helps the Program Chair know how "
                                   + "you came to your conclusion.");
    my_ta_rationale.setWrapStyleWord(true);
    my_ta_rationale.setRows(Standards.TEXT_AREA_LARGE_ROWS);
    my_ta_rationale.setLineWrap(true);
    
    panel_rationale.add(createScrollPane(my_ta_rationale), BorderLayout.SOUTH);
    
    return panel_form;
  }
  
  /**
   * Creates the columned portion of the form panel.
   * @return The columned panel.
   */
  private JPanel createColumnedPanel() {
    final JPanel panel_column_split = new JPanel();
    panel_column_split.setBackground(Standards.COLOR_BACKGROUND);
    panel_column_split.setLayout(new BoxLayout(panel_column_split, BoxLayout.X_AXIS));

    panel_column_split.add(createLeftColumnPanel());
    panel_column_split.add(Box.createHorizontalStrut(Standards.STRUT_LENGTH_LARGE));
    panel_column_split.add(createRightColumnPanel());
    
    return panel_column_split;
  }
  
  /**
   * Creates the left column of the columned panel.
   * @return The left column panel.
   */
  private JPanel createLeftColumnPanel() {
    final JPanel panel_left_column = new JPanel();
    panel_left_column.setBackground(Standards.COLOR_BACKGROUND);
    panel_left_column.setLayout(new BoxLayout(panel_left_column, BoxLayout.Y_AXIS));
    
    final JPanel panel_spc_name = new JPanel();
    panel_spc_name.setBackground(Standards.COLOR_BACKGROUND);
    panel_spc_name.setLayout(new BorderLayout(0, 0));
    
    final JLabel lbl_spc_name = new JLabel("Subprogram Chair Name");
    
    my_tf_spc = new JTextField();
    my_tf_spc.setColumns(Standards.TEXT_BOX_HALF_WIDTH);
    
    final JPanel panel_manuscript_author = new JPanel();
    panel_manuscript_author.setBackground(Standards.COLOR_BACKGROUND);
    panel_manuscript_author.setLayout(new BorderLayout(0, 0));
    
    final JLabel lbl_manuscript_author = new JLabel("Manuscript Author");
    
    my_tf_manuscript_author = new JTextField();
    my_tf_manuscript_author.setColumns(Standards.TEXT_BOX_HALF_WIDTH);
    
    panel_left_column.add(panel_spc_name);
    panel_spc_name.add(lbl_spc_name, BorderLayout.CENTER);
    panel_spc_name.add(my_tf_spc, BorderLayout.SOUTH);
    panel_left_column.add(Box.createVerticalStrut(Standards.STRUT_LENGTH_MEDIUM));
    panel_left_column.add(panel_manuscript_author);
    panel_manuscript_author.add(lbl_manuscript_author, BorderLayout.CENTER);
    panel_manuscript_author.add(my_tf_manuscript_author, BorderLayout.SOUTH);
    
    return panel_left_column;
  }
  
  /**
   * Creates the right column of the columned panel.
   * @return The right column panel.
   */
  private JPanel createRightColumnPanel() {
    final JPanel panel_right_column = new JPanel();
    panel_right_column.setBackground(Standards.COLOR_BACKGROUND);
    panel_right_column.setLayout(new BoxLayout(panel_right_column, BoxLayout.Y_AXIS));
    
    final JPanel panel_conference = new JPanel();
    panel_conference.setBackground(Standards.COLOR_BACKGROUND);
    panel_conference.setLayout(new BorderLayout(0, 0));
    
    final JLabel lbl_conference_name = new JLabel("Conference Name");
    
    my_tf_conference_name = new JTextField();
    my_tf_conference_name.setColumns(Standards.TEXT_BOX_HALF_WIDTH);
    
    final JPanel panel_manuscript_title = new JPanel();
    panel_manuscript_title.setBackground(Standards.COLOR_BACKGROUND);
    panel_manuscript_title.setLayout(new BorderLayout(0, 0));
    
    final JLabel lbl_manuscript_title = new JLabel("Manuscript Title");
    
    my_tf_manuscript_title = new JTextField();
    my_tf_manuscript_title.setColumns(Standards.TEXT_BOX_HALF_WIDTH);

    panel_right_column.add(panel_conference);
    panel_conference.add(lbl_conference_name, BorderLayout.CENTER);
    panel_conference.add(my_tf_conference_name, BorderLayout.SOUTH);
    panel_right_column.add(Box.createVerticalStrut(Standards.STRUT_LENGTH_MEDIUM));
    panel_right_column.add(panel_manuscript_title);
    panel_manuscript_title.add(lbl_manuscript_title, BorderLayout.CENTER);
    panel_manuscript_title.add(my_tf_manuscript_title, BorderLayout.SOUTH);
    
    return panel_right_column;
  }


  /**
   * Completes the Recommendation form and submits it to the database.
   * @return The Recommendation form.
   */
  private Recommendation submitForm() {
    final Recommendation r = inputToRecommendation();
    my_recommendation_access.createRec(r);
    my_recommendation = r;
    return r;
  }
  
  /**
   * Edits the Recommendation and submits the changes to the database.
   * @return The Recommendation.
   */
  private Recommendation editForm() {
    final Recommendation r = inputToRecommendation();
    r.setID(my_recommendation.getID());
    my_recommendation_access.editRec(r);
    return r;
  }
  
  /**
   * Converts form input into a Recommendation object.
   * @return The Recommendation.
   */
  private Recommendation inputToRecommendation() {
    final List<String> field_values = new ArrayList<String>();
    field_values.add(my_tf_spc.getText());
    field_values.add(my_tf_conference_name.getText());
    field_values.add(my_tf_manuscript_author.getText());
    field_values.add(my_tf_manuscript_title.getText());
    final int n = getRadioButtonIndexInGroup(my_group_summary);
    //TODO Hook this up with DataAccess so that the resulting form can exist in a
    //persistent state.  If quick testing is needed, just put the form in a static
    //location and then construct a new panel with the form as a parameter.
    return new Recommendation(0, field_values, n, my_ta_rationale.getText());
  }
  
  /**
   * Populates the form using a previously filled out form.
   * @param the_r The recommendation form that was filled out previously.
   */
  private void populateFields(final Recommendation the_r) {
    my_tf_spc.setText(the_r.getSubprogramChairName());
    my_tf_conference_name.setText(the_r.getConference());
    my_tf_manuscript_author.setText(the_r.getManuscriptAuthor());
    my_tf_manuscript_title.setText(the_r.getManuscriptTitle());
    setRadioButtonInGroup(my_group_summary, the_r.getSummaryRating());
    my_ta_rationale.setText(the_r.getRationale());
  }
  
  /**
   * {@inheritDoc}
   */
  @Override
  public String getPanelLabel() {
    return "Recommendation";
  }
  
  /**
   * Sets the parameters dependent on the user filling out the form.
   * @param the_spc The SubprogramChair data object.
   */
  private void setUserFields(final SubprogramChair the_spc) {
    lockInText(my_tf_spc, the_spc.getUser().getFullName());
  }
  
  /**
   * Sets the parameters dependent on the conference that the user is filling
   * out the form for.
   * @param the_conference The Conference data object.
   */
  private void setConferenceFields(final Conference the_conference) {
    lockInText(my_tf_conference_name, the_conference.getTitle());
  }
  
  /**
   * Sets the parameters dependent on the conference that the user is filling
   * out the form for.
   * @param the_manuscript The Manuscript data object.
   */
  private void setManuscriptFields(final Manuscript the_manuscript) {
    lockInText(my_tf_manuscript_title, the_manuscript.getTitle());
    lockInText(my_tf_manuscript_author, the_manuscript.getSubmittingAuthor());
  }
  
  /**
   * Sets the text of the text field and then makes it uneditable.
   * @param the_field The text component to set the text for.
   * @param the_str   The String to be displayed.
   */
  private void lockInText(final JTextComponent the_field, final String the_str) {
    the_field.setText(the_str);
    the_field.setEditable(false);
  }

}
